##############################################################################
# jq 命令速查表
# 轻量级且灵活的命令行 JSON 处理器
# 来源：https://github.com/funnyzak/cli-cheatsheets
# 官方手册：https://stedolan.github.io/jq/manual/
##############################################################################

# 图例:
#   - FILTER: jq 表达式，用于选择/转换数据 (例如: '.', '.name', '.[0]', 'map(.id)')
#   - KEY:    对象键名 (字符串)
#   - INDEX:  数组索引 (整数，从0开始)
#   - VALUE:  JSON 值 (字符串、数字、布尔值、数组、对象、null)
#   - VAR:    jq 中的变量名 (以 $ 开头)
#   - STR:    字符串值

##############################################################################
# 基本用法 & 命令行选项
##############################################################################

# 基本语法: jq [选项] 过滤器 [文件...]
# 从文件或标准输入读取 JSON

jq '过滤器' data.json                     # 处理文件
cat data.json | jq '过滤器'               # 处理标准输入
echo '{"a": 1}' | jq '过滤器'            # 处理字符串

# 常用选项:
jq -r '过滤器'                           # 原始字符串输出 (字符串不带 JSON 引号)
jq -c '过滤器'                           # 紧凑输出 (每个 JSON 对象占一行)
jq -s '过滤器'                           # 吸入模式: 将所有输入读取到单个数组中
jq -n '过滤器'                           # 空输入: 不读取标准输入直接运行过滤器 (适用于生成 JSON)
jq --arg 变量名 值 '过滤器'               # 将字符串值作为变量传递
jq --argjson 变量名 JSON值 '过滤器'       # 将 JSON 值作为变量传递
jq -f script.jq data.json                # 从文件中读取过滤器

##############################################################################
# 基本过滤器
##############################################################################

.                                         # 恒等: 原样输出整个输入
.key                                      # 通过键名访问对象值
."key-with-special-chars"                 # 使用引号访问特殊字符的键
.[INDEX]                                  # 通过索引访问数组元素 (从0开始)
.[START:END]                              # 数组切片 (提取子数组; END 是排除的)
.key1.key2                                # 访问嵌套值
.key // "默认值"                          # 如果 .key 为 null 或 false 则提供默认值
.[INDEX]?                                 # 如果索引不存在则抑制错误
.key?                                     # 如果键不存在则抑制错误

##############################################################################
# 数组和对象操作
##############################################################################

.[]                                       # 遍历数组元素或对象值
.[], .[]                                  # 笛卡尔积 (谨慎使用)
map(过滤器)                               # 对输入数组的每个元素应用过滤器
select(布尔表达式)                         # 输出布尔表达式为真的输入项
[过滤器1, 过滤器2, ...]                   # 从过滤器结果创建数组
{键1: 过滤器1, 键2: 过滤器2, ...}         # 从过滤器结果创建对象
{key1, key2: .another_key}               # 简写: {key1: .key1, key2: .another_key}

keys                                      # 获取对象键名作为数组
length                                    # 获取数组长度、字符串长度或对象键数量
has(键名)                                 # 检查对象是否有特定键 (返回布尔值)
del(.key)                                 # 从对象中删除键值对
del(.[INDEX])                             # 从数组中删除元素
.+                                        # 加法 (数字)、连接 (字符串、数组、对象)

##############################################################################
# 内置函数 (常用)
##############################################################################

# 类型和转换
type                                      # 获取值的类型 ("string", "number", "array" 等)
tostring                                  # 将值转换为字符串
tonumber                                  # 将值转换为数字 (如果不可能则报错)
tojson                                    # 将值转换为 JSON 文本
fromjson                                  # 将 JSON 文本解析为值

# 字符串操作
startswith(字符串)                         # 检查字符串是否以指定字符串开头
endswith(字符串)                           # 检查字符串是否以指定字符串结尾
contains(字符串)                           # 检查字符串是否包含指定字符串
split(字符串)                              # 使用指定字符串作为分隔符将字符串拆分为数组
join(字符串)                               # 使用指定字符串作为分隔符连接字符串数组
test(正则表达式)                           # 测试字符串是否匹配正则表达式 (PCRE)

# 数组操作
flatten                                   # 将嵌套数组展平一级
unique                                    # 从数组中删除重复项
sort                                      # 对数组排序
reverse                                   # 反转数组
in(数组)                                  # 检查输入值是否存在于数组中

# 数学运算
max, min, add                             # 对数字数组的常用数学函数

##############################################################################
# 流程控制 & 变量
##############################################################################

过滤器1 | 过滤器2                          # 将过滤器1的输出管道输入到过滤器2
过滤器1 , 过滤器2                          # 用相同输入先运行过滤器1，再运行过滤器2。产生多个输出。
if 条件 then 真过滤器 else 假过滤器 end    # 条件执行
try 过滤器 catch 处理器                    # 错误处理 (处理器接收错误信息)
值 as $变量 | 过滤器                       # 将值分配给变量 $变量 以在过滤器中使用
reduce 输入 as $项 (初始值; 更新)          # 归约/折叠操作

##############################################################################
# 实用技巧
##############################################################################

# 提取多个字段到 TSV/CSV (使用 -r):
#   jq -r '[.name, .version, .author.email] | @tsv' package.json
#   jq -r '[.id, .status] | @csv' data.json

# 美化 JSON (默认行为):
#   cat ugly.json | jq .

# 过滤数组元素:
#   jq '.users | map(select(.active == true))' data.json
#   jq '.items[] | select(.price > 100)' data.json

# 即时创建简单 JSON (使用 -n):
#   jq -n '{user: "admin", id: 123, active: true}'

# 在 jq 过滤器中使用 shell 变量:
#   MYVAR="some_value"
#   jq --arg v "$MYVAR" '.items[] | select(.name == $v)' data.json

# 调试过滤器:
#   jq 'debug' data.json                     # 显示过滤器执行步骤

##############################################################################
# 示例
##############################################################################

# 示例 JSON (data.json):
# {
#   "name": "my-package",
#   "version": "1.0.0",
#   "dependencies": [
#     {"name": "libA", "version": "2.1"},
#     {"name": "libB", "version": "3.0"}
#   ],
#   "author": {"name": "Anon", "email": "anon@example.com"}
# }

# 获取包名:
#   jq '.name' data.json
# 输出: "my-package"

# 获取原始字符串形式的包名:
#   jq -r '.name' data.json
# 输出: my-package

# 获取所有依赖的名称:
#   jq '.dependencies[].name' data.json
# 输出: "libA"
#       "libB"

# 获取依赖名称的 JSON 数组:
#   jq '[.dependencies[].name]' data.json
# 输出: ["libA", "libB"]

# 获取版本号 > 2.5 的依赖的名称和版本:
#   jq '.dependencies[] | select(.version | tonumber > 2.5) | {name, version}' data.json
# 输出: { "name": "libB", "version": "3.0" }

# 创建摘要对象:
#   jq '{package_name: .name, author_email: .author.email, dep_count: (.dependencies | length)}' data.json
# 输出: { "package_name": "my-package", "author_email": "anon@example.com", "dep_count": 2 }

##############################################################################
# 鸣谢 & 更多资源
##############################################################################

# jq 官方手册: https://stedolan.github.io/jq/manual/
# jq 官方教程: https://stedolan.github.io/jq/tutorial/
# jq 食谱: https://github.com/stedolan/jq/wiki/Cookbook
# jq 在线试验场: https://jqplay.org/

# vim: set ts=4 sw=4 tw=0 et ft=sh :
